#include <windows.h>
#include <iostream>
#include <conio.h>
  
using namespace std;
void ErrorView();


struct Descriptor
{
unsigned short limit_l;
unsigned short base_l;
unsigned char base_m;
unsigned char access;
unsigned char limit_h;
unsigned char base_h;       
};

struct FPWORD
{
    unsigned short  size;
    unsigned int base;
};
  
int main()
{
    DWORD status;
    char path[100]; GetCurrentDirectory(100, path);
    strcpy(path + strlen(path), "\\sys\\objchk_wxp_x86\\i386\\driver.sys");
    SC_HANDLE manager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); 
    SC_HANDLE service = CreateService(manager,"driver",
              "driver",SERVICE_ALL_ACCESS,
              SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL,
              path,0,0,0,0,0);
               


    StartService(service,0,0);
    HANDLE handle = CreateFile("\\\\.\\driver",GENERIC_READ|GENERIC_WRITE,
           FILE_SHARE_READ|FILE_SHARE_WRITE,
           NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if(handle == INVALID_HANDLE_VALUE) return 1;
                                       
    DeviceIoControl(handle,0,0,0,0,0,&status,0);
    
    char out[] = "gdt";
    DWORD outSize = sizeof(out);
    WriteFile(handle,out,outSize,&status,0);    
    char in[100];
    int inSize = sizeof(in);
    ReadFile(handle,in, inSize, &status, 0);
    FPWORD* gdt=(FPWORD*)in;
    int size = gdt->size;
    cout << "Size " << size << endl;
    cout << "Base " << gdt->base << endl;
    
    for(int i = 0; i < size; ++i)
    {
    itoa(i, out, 10);
    outSize = sizeof(out);
    WriteFile(handle,out,outSize,&status,0);
    
    char in[100];
    int inSize = sizeof(in);
    ReadFile(handle,in, inSize, &status, 0);
         Descriptor* gdtdesc=(Descriptor*)in;
    if (gdtdesc->limit_l)
    printf("Limit 0:15 %d, Limit 48:55 %d, Base 16:31 %d, Base 32:39 %d, Base 56:63 %d, Access %d\n",
          gdtdesc->limit_l, gdtdesc->limit_h, gdtdesc->base_l, gdtdesc->base_m,
          gdtdesc->base_h, gdtdesc->access);
        
}
    CloseHandle(handle);
    
    SERVICE_STATUS status_;
    ControlService(service,SERVICE_CONTROL_STOP,&status_);
    DeleteService(service);
    CloseServiceHandle(service);
    CloseServiceHandle(manager);
    while(!getch());
    return 0;
}
